﻿using Freebase4net.Operators;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Freebase4net.Tests
{
    [TestClass]
    public class MqlParserTests
    {
        [TestMethod]
        public void NewMqlParser_ObjectWithSImpleTypes()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.type = "/music/artist";
            thepolice.Int = 1;
            thepolice.Double = 1d;
            thepolice.Float = 1f;
            thepolice.Bool = true;
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"type\":\"/music/artist\",\r\n\"Int\":1,\r\n\"Double\":1,\r\n\"Float\":1,\r\n\"Bool\":True\r\n}]", parser.JsonString);
        }
        [TestMethod]
        public void NewMqlParser_DictionaryOfObjectsAndArrayWithEmptyObject()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = "The Scorpions";
            thepolice.album = new Dictionary<Object, Object>();
            thepolice.album.Add("name", null);
            thepolice.album.Add("limit", 2);
            thepolice.album.Add("genre", FreebaseHelpers.CreateArrayWithEmptyObject());
            var parser = new MqlParser(thepolice);
            Assert.AreEqual("[{\r\n\"name\":\"The Scorpions\",\r\n\"album\":[{\r\n\t\"name\":null,\r\n\t\"limit\":2,\r\n\t\"genre\":[{}]\r\n\t}]\r\n}]",
                parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_MultipleDictionaries()
        {
            dynamic director = new ExpandoObject();
            director.name = null;
            director.id = null;
            director.type = "/film/director";
            ((IDictionary<String, Object>)director).Add("a:film", new Dictionary<Object, Object>() {
                                                                                               {"name",null},
                                                                                               {"id",null},
                                                                                               {"starring",new Dictionary<Object,Object>()
                                                                                                   {
                                                                                                       {"actor","Tobey Maguire"}
                                                                                                   }
                                                                                               }    
                                                                                            });
            var parser = new MqlParser(director);
            Assert.AreEqual("[{\r\n\"name\":null,\r\n\"id\":null,\r\n\"type\":\"/film/director\",\r\n\"a:film\":[{\r\n\t\"name\":null,\r\n\t\"id\":null,\r\n\t\"starring\":[{\r\n\t\"actor\":\"Tobey Maguire\"\r\n\t}]\r\n\t}]\r\n}]",
                parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_ObjectWithLikeOperator()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = FreebaseHelpers.Operators.CreateLikeOperator("The Scorpions");
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"name\":null,\r\n\"name~=\":\"The Scorpions\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_ObjectWithOneOfOperatorAndListOfStrings()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = new OneOfOperator(new object[] { "The Scorpions", "Some song" });
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"name\":null,\r\n\"name|=\":[\"The Scorpions\", \"Some song\"]\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_ObjectWithButNotOperatorAndOneParamter()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = FreebaseHelpers.Operators.CreateButNotOperator("The Scorpions");
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"name\":null,\r\n\"name!=\":\"The Scorpions\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_ObjectWithButNotOperatorAndFewParamters()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = FreebaseHelpers.Operators.CreateButNotOperator("The Scorpions", "The Police", "The Matrix");
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"name\":null,\r\n\"name!=\":\"The Scorpions\",\r\n\"a:name!=\":\"The Police\",\r\n\"b:name!=\":\"The Matrix\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_ObjectWithAndOperatorAndTwoParamters()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = FreebaseHelpers.Operators.CreateAndOperator("The Scorpions", "The Police");
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"name\":\"The Scorpions\",\r\n\"and:name\":\"The Police\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_ObjectWithFewOperators()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.name = FreebaseHelpers.Operators.CreateMultiOparator(
                FreebaseHelpers.Operators.CreateOneOfOperator(new object[] { "The Scorpions", "Some song" }),
                FreebaseHelpers.Operators.CreateLikeOperator("The Scorpions")
            );
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"name\":null,\r\n\"name|=\":[\"The Scorpions\", \"Some song\"],\r\n\"name~=\":\"The Scorpions\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_GreaterThenOperator()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.length = FreebaseHelpers.Operators.CreateGreaterThenOperator("300");
            
            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"length\":null,\r\n\"length>\":\"300\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_LessThenOperator()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.length = FreebaseHelpers.Operators.CreateLessThenOperator("300");

            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"length\":null,\r\n\"length<\":\"300\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_GreaterThenOrEqualOperator()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.length = FreebaseHelpers.Operators.CreateGreaterThenOrEqualOperator("300");

            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"length\":null,\r\n\"length>=\":\"300\"\r\n}]", parser.JsonString);
        }

        [TestMethod]
        public void NewMqlParser_LessThenOrEqualOperator()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.length = FreebaseHelpers.Operators.CreateLessThenOrEqualOperator("300");

            var parser = new MqlParser(thepolice);

            Assert.AreEqual("[{\r\n\"length\":null,\r\n\"length<=\":\"300\"\r\n}]", parser.JsonString);
        }

        //[TestMethod]
        //public void NewMqlParser_MultipleQueries()
        //{
        //    dynamic thescorpions = new ExpandoObject();
        //    thescorpions.name = "The Scorpions";
        //    thescorpions.type = "/music/artist";

        //    dynamic thepolice = new ExpandoObject();
        //    thepolice.name = "The Police";
        //    thepolice.type = "/music/artist";
        //    var parser = new MqlParser(thescorpions, thepolice);

        //    Assert.AreEqual("{\r\n\"q1\":{\r\n\"query\":[{\r\n\t\"name\":\"The Scorpions\",\r\n\t\"type\":\"/music/artist\"\r\n\t}]},\r\n\"q2\":{\r\n\"query\":[{\r\n\t\"name\":\"The Police\",\r\n\t\"type\":\"/music/artist\"\r\n\t}]}\r\n}", parser.JsonString);
        //}
    }
}
